home *** CD-ROM | disk | FTP | other *** search
/ PC Graphics Unleashed / PC Graphics Unleashed.iso / ch12 / blobdraw.poc < prev    next >
Text File  |  1994-07-31  |  12KB  |  432 lines

  1. /////////////////////////////////////////////////////////////
  2. //                     BLOBDRAW.POC V 1.1                  //
  3. // Animated Blob Generator for Autodesk Animator Pro.      //
  4. // (c) 1994 James P. Hawkins                               //
  5. //          18 Marlpit Pl.                                 //
  6. //          Middletown, NJ 07748                           //
  7. //                                                         //
  8. // See "3D Artist", issue #14 PP. 41-42               //
  9. //     "Introduction to Blobs" by Alfonso Hermida          //
  10. //                               //
  11. /////////////////////////////////////////////////////////////
  12.  
  13. #pragma poco library "pdracces.poe"     // extended picture I/O library
  14. #pragma poco stacksize 32k
  15. #include <errcodes.h>
  16.  
  17. #define MAXBLOBS 100
  18.  
  19. int     color,
  20.         numcol,         // Screen width in pixels
  21.         numrow,         // Screen height in pixels
  22.         curframe,       // Current frame
  23.         skip = 1.0,     // Set skip > 1.0 for faster spaced out pixel plot
  24.         num_frames,     // Total number of frames
  25.         color_mode = 1, // Color exponential gradient if default
  26.         old_color_idx;  // To save previous color
  27.  
  28. // Blob space is 8 X 6 with 0 at center
  29.  
  30. double  xmin = -4.0,
  31.         ymin = -3.0,
  32.         xmax = 4.0,
  33.         ymax = 3.0,
  34.         threshold = 0.5;
  35.  
  36.  
  37. FILE *fp;
  38.  
  39. ///////////////////////////////////////////////////////////////////
  40. // BLOB DATUM
  41. // x, y is the center in BLOB space (-4 < x < 4, -3 < y < 3)
  42. // dx, dy are the amount x and y are incremented or decremented
  43. // for motion to the next frame, they will be 0 if the blob is
  44. // stationary.
  45. // radius is the blob radius in BLOB space units
  46. // and strength is the max strength at the blob center.
  47. ///////////////////////////////////////////////////////////////////
  48.  
  49. typedef struct {
  50.     double x,y;            // Center of blob
  51.     double dx, dy;       // animation motion deltas
  52.     double radius, strength;
  53. } BLOB;
  54.  
  55. BLOB    blobs[MAXBLOBS];
  56. int     bnum;           // Blob number
  57.  
  58. // Function prototypes
  59. void blobdemo(void);
  60. void blobinc(void);
  61. int  blobinfo(void);
  62. void GrayPaletteInit(void);
  63.  
  64. ////////////////////////////////////////////////////
  65. // MENUS
  66. char main_header[] = "Main menu";
  67. int main_choice;
  68. char *main_choices[] =    {
  69.     "CREATE BLOB SCENE",
  70.     "DEMO",
  71.     };
  72.  
  73. enum {
  74.     MAIN_DEMO,
  75.     MAIN_BLOB_INFO,
  76.     };
  77.  
  78. //////////////////////////////////////////////////
  79. //                     MAIN                     //
  80. //////////////////////////////////////////////////
  81.  
  82. main()
  83. {
  84.  
  85.     double r, t, x, y, temp;
  86.     int i, j, k;
  87.   
  88.     int max_strength;      // The highest strength possible (for color calc)
  89.  
  90.     GetPhysicalSize(&numcol, &numrow);  // Get the screen res from anipro
  91.  
  92.     num_frames = GetFrameCount();          // Get number of frames available
  93.  
  94.     old_color_idx = GetColor(); // Save old color index
  95.  
  96.     // Display the main menu and act on the choice
  97.     main_choice = Qmenu(main_choices, 2, main_header);
  98.     switch (main_choice)
  99.     {
  100.     case MAIN_DEMO:
  101.         blobdemo();
  102.         break;
  103.     case MAIN_BLOB_INFO:
  104.         if(!blobinfo())
  105.             return;
  106.     }
  107.     
  108.     for(curframe = 1; curframe <= num_frames; curframe++)
  109.     {
  110.         Clear();       // clear screen
  111.         printf("Generating frame %d of %d.", curframe, num_frames);
  112.  
  113.         for(j = 0;j <= numrow; j += skip) {
  114.             y = j * (ymax - ymin) / numrow + ymin;
  115.             for(i = 0; i <= numcol; i += skip) {
  116.                 x = i * (xmax - xmin) / numcol + xmin;
  117.                 t = 0.0;
  118.                 // Add the combined strengths of the blobs at this point
  119.                 for(k = 0; k < bnum; k++) {
  120.  
  121.                     // Calculate distance from blob center
  122.                 r = sqrt((x - blobs[k].x) * (x - blobs[k].x)  +
  123.                          (y - blobs[k].y) * (y - blobs[k].y));
  124.                     //
  125.                     // If distance is within blob radius calculate 't'
  126.                     // from: t = strength(1 - (r/radius)^2)^2
  127.                     //
  128.                     if( r <= blobs[k].radius ) {
  129.                     temp = r / blobs[k].radius;
  130.                         temp *= temp;
  131.                     temp = 1.0 - temp;
  132.                     temp *= temp;
  133.                     t += blobs[k].strength * temp;
  134.                     }
  135.                 }
  136.  
  137.                 //
  138.                 // If the combined strength at this coordinate exceeds
  139.                 // the threshold, plot a point.
  140.                 // If color mode is on, the color is a function of
  141.                 // the strength, based on 256 color palette.
  142.                 //
  143.                 if (t >= threshold) {
  144.                     switch(color_mode) {
  145.                     case 0:
  146.                         color = GetColor();
  147.                         break;
  148.                     case 1:
  149.                         color = 255 * (1 - exp(-t));
  150.                         if(t == threshold) color /= 4;
  151.                         break;
  152.                     case 2:
  153.                         color = 255 * exp(-t);
  154.                         break;
  155.                     case 3:
  156.                         color = t * 255;
  157.                         if(color > 255)
  158.                             color = 255;
  159.                         break;
  160.             case 4:
  161.                         // Calculate maximum possible strength for use
  162.                         // in computing color index
  163.                         for(k = 0, max_strength = 0.0; k < bnum; k++)
  164.                             max_strength += blobs[k].strength;
  165.  
  166.                         color = ((int)((t/max_strength) * 255) % 255);
  167.                         break;
  168.                     case 5:
  169.                         color = t * 255;
  170.                         break;
  171.  
  172.                     }
  173.                     SetColor(color);
  174.                     Dot(i, j);  
  175.                 }
  176.             }
  177.         }
  178.         NextFrame();
  179.         blobinc();
  180.     }
  181.     SetColor(old_color_idx);
  182.     unprintf();
  183. }
  184.  
  185. ////////////////////////////////////////////////////////////
  186. // MOVE ALL BLOBS FOR NEXT FRAME
  187. //
  188.  
  189. void blobinc(void)
  190. {
  191.  
  192.     int k;
  193.  
  194.     for(k = 0; k < bnum; k++)
  195.     {
  196.         blobs[k].x += blobs[k].dx;
  197.         blobs[k].y += blobs[k].dy;
  198.     }
  199. }
  200.  
  201.  
  202. //////////////////////////////
  203. //   BLOB MENU DEFINITIONS  //
  204. //////////////////////////////
  205. //      
  206. int blob_choice = -1; 
  207. char blob_header[] = "BLOB DATA ENTRY";
  208. char *blob_choices[] =    {
  209.     "Add A Blob",
  210.     "Set Threshold Index (default = 5)",
  211.     "Set Color Mode",
  212.     "Set Palette to Grayscale",
  213.     "GO!",
  214.     };
  215.  
  216. enum {
  217.     BLOB_GO,
  218.     BLOB_ADD_BLOB,
  219.     BLOB_SET_THRESH,
  220.     BLOB_SET_COLOR_MODE,
  221.     BLOB_GRAY,
  222.     };
  223.  
  224. double tenths[21] = {-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2,
  225.  -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};
  226.  
  227. ////////////////////////////////////////////////////////////////////////
  228. // ENTER YOUR OWN BLOB ANIMATION DATA
  229. //
  230. int blobinfo(void)
  231. {
  232.  
  233.     int i1, j1, i2, j2, radius, threshindex = 5, strengthindex = 10;
  234.     double x1, x2, y1, y2;
  235.     int go_flag = 0;
  236.     int old_red, old_green, old_blue;
  237.     int old_filled;
  238.  
  239. #ifdef DEBUG
  240.     fp = fopen("pdump.txt", "w");
  241. #endif
  242.     // Temporarily put WHITE in index 1 and use it for
  243.     // the blob placement and path, restore the old color in
  244.     // index 1 when done.
  245.     SetColor(1);  
  246.     GetColorMap(1, &old_red, &old_green, &old_blue);
  247.     SetColorMap(1, 255, 255, 255);
  248.     //
  249.     // Temporarily set to NON-FILLED mode to make the
  250.     // BLOB outlines and paths easier to see.
  251.     //
  252.     old_filled = GetFilled();
  253.     SetFilled(0);
  254.  
  255.     bnum = 0;
  256.  
  257.     while (blob_choice != BLOB_GO)
  258.     {
  259.       blob_choice = Qmenu(blob_choices, 5, blob_header);
  260.  
  261.       switch (blob_choice)
  262.       {
  263.       case BLOB_GO:
  264.           go_flag++;
  265.           break;
  266.       case BLOB_SET_THRESH:
  267.           Qnumber(&threshindex, 0, 10, "SET THRESHOLD INDEX");
  268.           threshold = tenths[threshindex + 10];
  269.           break;
  270.       case BLOB_SET_COLOR_MODE:
  271.           Qnumber(&color_mode, 0, 5, "SET COLOR MODE");
  272.           break;
  273.       case BLOB_GRAY:
  274.           GrayPaletteInit();
  275.           GetColorMap(1, &old_red, &old_green, &old_blue);
  276.           SetColorMap(1, 255, 255, 255);
  277.           break;
  278.       case BLOB_ADD_BLOB:
  279.           if(RubCircle(&i1, &j1, &radius)) // Get center and radius
  280.               Circle(i1, j1, radius);     // Draw a circle
  281.           else
  282.               return(0);
  283.  
  284.           if(!RubLine(i1, j1, &i2, &j2)) { // Get motion path
  285.               i2 = i1;             
  286.               j2 = j1;
  287.           }
  288.           Line(i1, j1, i2, j2);         // Draw the path
  289.           y1 = (double)j1 * (ymax - ymin) / numrow + ymin;
  290.           y2 = (double)j2 * (ymax - ymin) / numrow + ymin;
  291.           x1 = (double)i1 * (xmax - xmin) / numcol + xmin;
  292.           x2 = (double)i2 * (xmax - xmin) / numcol + xmin;
  293.  
  294.           strengthindex = 10;
  295.           Qnumber(&strengthindex, -10, 10, "SET BLOB STRENGTH INDEX");
  296.           strengthindex += 10;
  297.  
  298.           blobs[bnum].x = x1;
  299.           blobs[bnum].y = y1;
  300.           blobs[bnum].radius = (double)radius * (ymax - ymin) / numrow;
  301.           blobs[bnum].strength = tenths[strengthindex];
  302.           blobs[bnum].dx = (x2 - x1) / num_frames;
  303.           blobs[bnum].dy = (y2 - y1) / num_frames;
  304.           bnum++;
  305. #ifdef DEBUG
  306.           fprintf(fp,"\nblobs[%d].x = %f\n", bnum, blobs[bnum].x);
  307.           fprintf(fp,"blobs[%d].y = %f\n", bnum, blobs[bnum].y);
  308.           fprintf(fp,"blobs[%d].radius = %f\n", bnum, blobs[bnum].radius);
  309.           fprintf(fp,"blobs[%d].strength = %f\n", bnum, blobs[bnum].strength);
  310.           fprintf(fp,"blobs[%d].dx = %f\n", bnum, blobs[bnum].dx);
  311.           fprintf(fp,"blobs[%d].dy = %f\n\n", bnum, blobs[bnum].dy);
  312. #endif
  313.           break;
  314.       }
  315.       if(go_flag){
  316.           break;
  317.       }
  318.  
  319.     }
  320. #ifdef debug
  321.     fprintf(fp,"\nbnum = %d\n", bnum);
  322.     fclose(fp);
  323. #endif
  324.     // Restore old color in index 1 and old filled mode.
  325.     SetFilled(old_filled);
  326.     SetColorMap(1, old_red, old_green, old_blue);
  327.     if(!color_mode)
  328.         SetColor(old_color_idx);
  329.     return(1);
  330. }
  331.  
  332. /////////////////////////////////////////////////////////////
  333. // DEMONSTRATION
  334. //
  335.  
  336. void blobdemo(void)
  337. {
  338. //
  339. // DEMO BLOBS
  340. //
  341.   // define blob #1
  342.   blobs[0].x = -3.0;
  343.   blobs[0].y = 0;
  344.   blobs[0].radius = 1.0;
  345.   blobs[0].strength = 1.0;
  346.   blobs[0].dx = 0.25;
  347.   blobs[0].dy = 0.0;
  348.  
  349.   // define blob #2
  350.   blobs[1].x = -1.375;
  351.   blobs[1].y = 0.64952;
  352.   blobs[1].radius = 1.0;
  353.   blobs[1].strength = 1.0;
  354.   blobs[1].dx = 0.0;
  355.   blobs[1].dy = 0.0;
  356.  
  357.   // define blob #3
  358.   blobs[2].x = -1.375;
  359.   blobs[2].y = -0.64952;
  360.   blobs[2].radius = 1.0;
  361.   blobs[2].strength = 1.0;
  362.   blobs[2].dx = 0.0;
  363.   blobs[2].dy = 0.0;
  364.  
  365.   // define blob #4
  366.   blobs[3].x = 0.625;
  367.   blobs[3].y = 0.64952;
  368.   blobs[3].radius = 1.0;
  369.   blobs[3].strength = 1.0;
  370.   blobs[3].dx = 0.0;
  371.   blobs[3].dy = 0.0;
  372.  
  373.   // define blob #5
  374.   blobs[4].x = 0.625;
  375.   blobs[4].y = -0.64952;
  376.   blobs[4].radius = 1.0;
  377.   blobs[4].strength = 1.0;
  378.   blobs[4].dx = 0.0;
  379.   blobs[4].dy = 0.0;
  380.  
  381.   // define blob #6
  382.   blobs[5].x = 2.625;
  383.   blobs[5].y = 0.64952;
  384.   blobs[5].radius = 1.0;
  385.   blobs[5].strength = 1.0;
  386.   blobs[5].dx = 0.0;
  387.   blobs[5].dy = 0.0;
  388.  
  389.   // define blob #7
  390.   blobs[6].x = 2.625;
  391.   blobs[6].y = -0.64952;
  392.   blobs[6].radius = 1.0;
  393.   blobs[6].strength = 1.0;
  394.   blobs[6].dx = 0.0;
  395.   blobs[6].dy = 0.0;
  396.  
  397.   bnum = 7;
  398.   color_mode = 4;
  399. }
  400.  
  401.  
  402.  
  403.  
  404. //////////////////////////////////////////////////////////////////////////
  405. //
  406. //
  407. void GrayPaletteInit(void)
  408. {
  409.  
  410.     int index;
  411.     int Palette_Map[256][3];
  412.  
  413.     for (index = 0; index < 256; index++)
  414.     {
  415.  
  416.       // Gray Gradient
  417.       Palette_Map[index][0] = index;
  418.       Palette_Map[index][1] = index;
  419.       Palette_Map[index][2] = index;
  420.     }
  421.  
  422.     // Set the palette for all frames, then reset to the first frame
  423.     SetFrame(0);
  424.     for(curframe = 1; curframe <= num_frames; curframe++) {
  425.         SetScreenColorMap(GetPicScreen(), &Palette_Map[0][0]);
  426.         NextFrame();
  427.     }
  428.     SetFrame(0);
  429.  
  430. }
  431.  
  432.